package com.cmc.cloud.cmclink.doc.service.impl.special;

import com.baomidou.lock.annotation.Lock4j;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.SpecialCargoMaximumErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.vo.specialcargomaximumvo.SpecialCargoMaximumBaseVO;
import com.cmc.cloud.cmclink.doc.vo.specialcargomaximumvo.SpecialCargoMaximumCreateReqVO;
import com.cmc.cloud.cmclink.doc.vo.specialcargomaximumvo.SpecialCargoMaximumPageReqVO;
import com.cmc.cloud.cmclink.doc.vo.specialcargomaximumvo.SpecialCargoMaximumUpdateReqVO;
import com.cmes.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import com.cmes.framework.common.pojo.PageResult;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;

import java.util.*;

import com.cmc.cloud.cmclink.doc.service.special.SpecialCargoMaximumService;
import com.cmc.cloud.cmclink.doc.entity.SpecialCargoMaximumDO;
import com.cmc.cloud.cmclink.doc.convert.SpecialCargoMaximumConvert;
import com.cmc.cloud.cmclink.doc.mapper.SpecialCargoMaximumMapper;


/**
 * 单船特种货最大装载量限制维护 Service 实现类
 *
 * @author 集运管理员
 */
@Service
@Validated
public class SpecialCargoMaximumServiceImpl implements SpecialCargoMaximumService {

    @Resource
    private SpecialCargoMaximumMapper specialCargoMaximumMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Lock4j(name = "specialCargoMaximumUnique", keys = {"#createReqVO.getLaneCode", "#createReqVO.getVesselCode"})
    public void createSpecialCargoMaximum(SpecialCargoMaximumCreateReqVO createReqVO) {
        // 插入
        validateUniqueExists(createReqVO, null);
        SpecialCargoMaximumDO specialCargoMaximum = SpecialCargoMaximumConvert.INSTANCE.convert(createReqVO);
        specialCargoMaximumMapper.insert(specialCargoMaximum);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Lock4j(name = "specialCargoMaximumUnique", keys = {"#updateReqVO.getLaneCode", "#updateReqVO.getVesselCode"})
    public void updateSpecialCargoMaximum(SpecialCargoMaximumUpdateReqVO updateReqVO) {
        // 校验存在
        validateSpecialCargoMaximumExists(updateReqVO.getId());
        validateUniqueExists(updateReqVO, updateReqVO.getId());
        // 更新
        SpecialCargoMaximumDO updateObj = SpecialCargoMaximumConvert.INSTANCE.convert(updateReqVO);
        specialCargoMaximumMapper.updateById(updateObj);
    }

    @Override
    public void deleteSpecialCargoMaximum(Long id) {
        // 校验存在
        validateSpecialCargoMaximumExists(id);
        // 删除
        specialCargoMaximumMapper.deleteById(id);
    }

    private void validateSpecialCargoMaximumExists(Long id) {
        if (specialCargoMaximumMapper.selectById(id) == null) {
            throw ServiceExceptionUtil.exception(SpecialCargoMaximumErrorCodeConstants.SPECIAL_CARGO_MAXIMUM_NOT_EXISTS);
        }
    }

    private void validateUniqueExists(SpecialCargoMaximumBaseVO vo, Long id) {
        LambdaQueryWrapperX<SpecialCargoMaximumDO> queryWrapperX = new LambdaQueryWrapperX<SpecialCargoMaximumDO>()
                .eqIfPresent(SpecialCargoMaximumDO::getVesselCode, vo.getVesselCode())
                .eqIfPresent(SpecialCargoMaximumDO::getLaneCode, vo.getLaneCode());
        if (id != null) {
            queryWrapperX.ne(SpecialCargoMaximumDO::getId, id);
        }
        if (ObjectUtils.isEmpty(vo.getDgTeu()) && ObjectUtils.isEmpty(vo.getFlexiTeu()) && ObjectUtils.isEmpty(vo.getOdoTeu()) && ObjectUtils.isEmpty(vo.getOogTeu())) {
            throw ServiceExceptionUtil.exception(SpecialCargoMaximumErrorCodeConstants.SPECIAL_CARGO_TEU_NEED);
        }
        if (specialCargoMaximumMapper.selectCount(queryWrapperX) != 0L) {
            throw ServiceExceptionUtil.exception(SpecialCargoMaximumErrorCodeConstants.SPECIAL_CARGO_MAXIMUM_EXISTED);
        }
    }

    @Override
    public SpecialCargoMaximumDO getSpecialCargoMaximum(Long id) {
        return specialCargoMaximumMapper.selectById(id);
    }

    @Override
    public List<SpecialCargoMaximumDO> getSpecialCargoMaximumList(Collection<Long> ids) {
        return specialCargoMaximumMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<SpecialCargoMaximumDO> getSpecialCargoMaximumPage(SpecialCargoMaximumPageReqVO reqVO) {
        LambdaQueryWrapperX<SpecialCargoMaximumDO> queryWrapperX = new LambdaQueryWrapperX<SpecialCargoMaximumDO>()
                .eqIfPresent(SpecialCargoMaximumDO::getLaneCode, reqVO.getLaneCode())
                .eqIfPresent(SpecialCargoMaximumDO::getVesselCode, reqVO.getVesselCode());
        return specialCargoMaximumMapper.selectPage(reqVO, queryWrapperX);
    }
}
